package geekbang.builder;

import org.springframework.util.StringUtils;

/**
 * @author xuyanqing
 * @description 建造者模式，如果构造函数参数过多，我们就需要考虑使用建造者模式
 * 建造者模式和工厂模式区别，经典例子：
 * 顾客走进一家餐馆点餐，我们利用工厂模式，根据用户不同的选择，来制作不同的食物，比
 * 如披萨、汉堡、沙拉。对于披萨来说，用户又有各种配料可以定制，比如奶酪、西红柿、起
 * 司，我们通过建造者模式根据用户选择的不同配料来制作披萨。
 * @date 2025-10-16 16:26
 * @creed where there is a will,there is a way. yx
 */

public class ResourcePoolConfig {

    private String name;
    private int maxTotal;
    private int maxIdle;
    private int minIdle;

    private ResourcePoolConfig(Builder builder) {
        this.name = builder.name;
        this.maxTotal = builder.maxTotal;
        this.maxIdle = builder.maxIdle;
        this.minIdle = builder.minIdle;
    }
    //...省略getter方法...

    //我们将Builder类设计成了ResourcePoolConfig的内部类。
    //我们也可以将Builder类设计成独立的非内部类ResourcePoolConfigBuilder。
    public static class Builder {
        private static final int DEFAULT_MAX_TOTAL = 8;
        private static final int DEFAULT_MAX_IDLE = 8;
        private static final int DEFAULT_MIN_IDLE = 0;

        private String name;
        private int maxTotal = DEFAULT_MAX_TOTAL;
        private int maxIdle = DEFAULT_MAX_IDLE;
        private int minIdle = DEFAULT_MIN_IDLE;

        public ResourcePoolConfig build() {
            // 校验逻辑放到这里来做，包括必填项校验、依赖关系校验、约束条件校验等
            if (StringUtils.isEmpty(name)) {
                throw new IllegalArgumentException("资源名称不能为空");
            }
            if (maxIdle > maxTotal) {
                throw new IllegalArgumentException("最大空闲资源数不能大于最大总资源数");
            }
            if (minIdle > maxTotal || minIdle > maxIdle) {
                throw new IllegalArgumentException("最小空闲资源数不能大于最大空闲资源数且最小空闲资源数不能大于最大总资源数");
            }

            return new ResourcePoolConfig(this);
        }

        public Builder setName(String name) {
            if (StringUtils.isEmpty(name)) {
                throw new IllegalArgumentException("资源名称不能为空");
            }
            this.name = name;
            return this;
        }

        public Builder setMaxTotal(int maxTotal) {
            if (maxTotal <= 0) {
                throw new IllegalArgumentException("最大总资源数不能为负数");
            }
            this.maxTotal = maxTotal;
            return this;
        }

        public Builder setMaxIdle(int maxIdle) {
            if (maxIdle <= 0) {
                throw new IllegalArgumentException("最大空闲资源数不能为负数");
            }
            this.maxIdle = maxIdle;
            return this;
        }

        public Builder setMinIdle(int minIdle) {
            if (minIdle < 0) {
                throw new IllegalArgumentException("最小空闲资源数不能为负数");
            }
            this.minIdle = minIdle;
            return this;
        }

        public static void main(String[] args) {
            ResourcePoolConfig config = new ResourcePoolConfig.Builder()
                    .setName("jdbc")
                    .setMaxTotal(5)
                    .setMaxIdle(10)
                    .setMinIdle(5)
                    .build();
            // 报错：最大空闲资源数不能大于最大总资源数
        }
    }
}
